//---------------------------------------------------------------------------------
// Copyright (c) 2011, Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//---------------------------------------------------------------------------------

namespace Microsoft.Samples.ServiceBus.SilverlightChat.Models.ViewModels
{
    using System;
    using System.Windows;
    using System.Windows.Documents;
    using Microsoft.Samples.ServiceBus.Messaging;

    /// <summary>
    /// Encapsulates a single message in a chat conversation including the text and its sender.
    /// </summary>
    public class ChatMessageViewModel : DependencyObject
    {
        public static readonly DependencyProperty UserNameProperty =
            DependencyProperty.Register("UserName", typeof(string), typeof(ChatMessageViewModel), new PropertyMetadata(string.Empty));

        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(string), typeof(ChatMessageViewModel), new PropertyMetadata(string.Empty));

        public ChatMessageViewModel()
            : this(string.Empty, string.Empty)
        {
        }

        public ChatMessageViewModel(string userName, string value)
        {
            this.UserName = userName;
            this.Value = value;
        }

        public string UserName
        {
            get { return (string)GetValue(UserNameProperty); }
            set { SetValue(UserNameProperty, value); }
        }

        public string Value
        {
            get { return (string)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

        /// <summary>
        /// From a brokered message, creates a ChatMessageViewModel detailing the
        /// body of the message as the value and the UserName message property as
        /// the username
        /// </summary>
        public static ChatMessageViewModel Create(BrokeredMessage message)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            string body = message.GetBody<string>();
            string user = "<anon>";
            if (message.Headers.ContainsKey("UserName"))
            {
                user = (string)message.Headers["UserName"];

                // Headers of type string will be enlosed in "double-quotes"
                if (user.Length > 1)
                {
                    user = user.Substring(1, user.Length - 2);
                }
            }

            return new ChatMessageViewModel(user, body);
        }

        /// <summary>
        /// Encodes this Chat Message as a Brokered Message. The body of the 
        /// message is set to the Message Value and a message property is added to
        /// contain the sending User's name
        /// </summary>
        internal BrokeredMessage CreateBrokeredMessage()
        {
            var result = new BrokeredMessage(this.Value);
            result.SetMessageProperty("UserName", this.UserName);

            return result;
        }

        /// <summary>
        /// For display purposes, creates a paragraph containing the username and 
        /// value of this chat message with the username formatted in bold. The
        /// result of this method can be appended to the BlockCollection of a rich
        /// text box
        /// </summary>
        internal Block CreateRichTextBlock()
        {
            return new Paragraph
            {
                Inlines = 
                    {
                        new Bold 
                        {
                            Inlines = { new Run { Text = this.UserName + ": " } }
                        },
                        new Run { Text = this.Value }
                    }
            };
        }
    }
}
